home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / abuse / src / view.c < prev   
C/C++ Source or Header  |  1996-04-12  |  27KB  |  1,176 lines

  1. #include "system.h"
  2. #include "view.hpp"
  3. #include "lisp.hpp"
  4. #include "jwindow.hpp"
  5. #include "config.hpp"
  6. #include "scroller.hpp"
  7. #include "id.hpp"
  8. #include "dev.hpp"
  9. #include "jrand.hpp" 
  10. #include "dprint.hpp"
  11. #include "transp.hpp"
  12. #include "clisp.hpp"
  13. #include "demo.hpp"
  14. #include "sbar.hpp"
  15. #include "nfserver.hpp"
  16. #include "chat.hpp"
  17.  
  18. #define SHIFT_DOWN_DEFAULT 15
  19. #define SHIFT_RIGHT_DEFAULT 0
  20.  
  21. extern window_manager *eh;
  22. view *player_list=NULL;
  23. int morph_sel_frame_color;
  24.  
  25. view::~view()
  26. {
  27.   if (local_player()) 
  28.     sbar.associate(NULL);
  29.  
  30.   if (total_weapons)
  31.   {
  32.     jfree(weapons);
  33.     jfree(last_weapons);
  34.   }
  35. }
  36.  
  37.  
  38. extern uchar bright_tint[256];
  39.  
  40. void view::add_ammo(int weapon_type, int total)
  41. {  
  42.   if (weapon_type>=total_weapons || weapon_type<0)
  43.   {
  44.     printf("weapon out of range\n");
  45.     return ;
  46.   }
  47.   if (weapons[weapon_type]==-1) return ;   // don't have weapon yet, can't give ammo
  48.   int rf=0;
  49.  
  50.   weapons[weapon_type]+=total;
  51.   if (weapons[weapon_type]<0)  
  52.     weapons[weapon_type]=0;  
  53.  
  54.   if (weapons[weapon_type]>999)
  55.     weapons[weapon_type]=999;
  56.  
  57.   if (weapon_total(current_weapon)==0 && current_weapon)
  58.   {
  59.     suggest.send_weapon_change=1;
  60.     if (DEFINEDP(symbol_value(l_switch_to_powerful)) && symbol_value(l_switch_to_powerful))
  61.     {
  62.       int x=total_weapons-1;
  63.       while (x>0 && (x==3 || weapons[x]<=0)) x--;         
  64.       suggest.new_weapon=x;
  65.     } else
  66.       suggest.new_weapon=0;
  67.   }
  68.  
  69. }
  70.  
  71. void view::give_weapon(int type) 
  72.   if (type>=total_weapons || type<0)
  73.   {
  74.     printf("weapon out of range\n");
  75.     return ;
  76.   }
  77.   if (weapons[type]==-1) 
  78.   { 
  79.     weapons[type]=0; 
  80.     sbar.need_refresh();
  81.   }
  82. }
  83.  
  84. int view::weapon_total(int type)
  85. {
  86.   if (type>=total_weapons || type<0)
  87.   {
  88.     printf("weapon out of range\n");
  89.     return 0;
  90.   }
  91.   if (god) return 100;
  92.   else if (weapons[type]==-1) return 0;
  93.   else return weapons[type];
  94. }
  95.  
  96.  
  97. long view::xoff()
  98. {
  99.   if (focus)
  100.   {
  101.     int x=last_x-(cx2-cx1+1)/2+shift_right+pan_x;
  102.     if (x<0) return 0;
  103.     else return x;
  104.   } else return pan_x;
  105. }
  106.  
  107. long view::interpolated_xoff()
  108. {
  109.   if (focus)
  110.   {
  111.     int x=(last_last_x+last_x)/2-(cx2-cx1+1)/2+shift_right+pan_x;
  112.     if (x<0) return 0;
  113.     else return x;
  114.   } else return pan_x;
  115. }
  116.  
  117.  
  118. long view::yoff()
  119. {
  120.   if (focus)
  121.   {
  122.     int y=last_y-(cy2-cy1+1)/2-shift_down+pan_y;
  123.     if (y<0) return 0;
  124.     else return y;
  125.   } else return pan_y;
  126. }
  127.  
  128.  
  129. long view::interpolated_yoff()
  130. {
  131.   if (focus)
  132.   {
  133.     int y=(last_y+last_last_y)/2-(cy2-cy1+1)/2-shift_down+pan_y;
  134.     if (y<0) return 0;
  135.     else return y;
  136.   } else return pan_y;
  137. }
  138.  
  139.  
  140. void view::update_scroll()
  141. {
  142.   if (focus)
  143.   {
  144.     last_last_x=last_x;
  145.     last_last_y=last_y;
  146.     if (focus->x>last_x)
  147.     {
  148.       if (focus->x-last_x>=no_xright)
  149.         last_x=focus->x-no_xright;
  150.     } else if (focus->x<last_x)
  151.     {
  152.       if (last_x-focus->x>=no_xleft)
  153.         last_x=focus->x+no_xleft;
  154.     }
  155.     if (focus->y>last_y)
  156.     {
  157.       if (focus->y-last_y>=no_ybottom)
  158.         last_y=focus->y-no_ybottom;
  159.     } else if (focus->y<last_y)
  160.     {
  161.       if (last_y-focus->y>=no_ytop)
  162.         last_y=focus->y+no_ytop;
  163.     }
  164.   }
  165. }
  166.  
  167. char cur_user_name[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  168.  
  169. #ifdef __WATCOMC__
  170. char *get_login()
  171. {  if (cur_user_name[0]) return cur_user_name; else return "DOS user"; }
  172.  
  173. #include <dos.h>
  174. #elif defined( __POWERPC__ )
  175.  
  176. char *get_login()
  177. {  if (cur_user_name[0]) return cur_user_name; else return "Mac user"; }
  178.  
  179. #else
  180. char *get_login()
  181. {  if (cur_user_name[0]) return cur_user_name; else return (getlogin() ? getlogin() : "unknown"); }
  182.  
  183. #endif
  184.  
  185. void set_login(char *name)
  186. { strncpy(cur_user_name,name,20); }
  187.  
  188. view::view(game_object *Focus, view *Next, int number)
  189.   chat_buf[0]=0; 
  190.  
  191.   draw_solid=-1;
  192.   no_xleft=0;
  193.   no_xright=0;
  194.   no_ytop=0;
  195.   no_ybottom=0;
  196.   if (Focus)
  197.   {
  198.     last_x=Focus->x;
  199.     last_y=Focus->y;
  200.   } else
  201.   {
  202.     last_x=last_y=0;
  203.   }
  204.  
  205.   last_last_x=last_x;
  206.   last_last_y=last_y;
  207.   last_hp=last_ammo=-1;
  208.   last_type=-1;
  209.   tsecrets=secrets=0;
  210.   tkills=kills=0;
  211.  
  212.   reset_keymap();
  213.  
  214.   ambient=32;
  215.   current_weapon=0;
  216.  
  217.   strcpy(name,get_login());
  218.   suggest.send_view=0;
  219.   suggest.send_weapon_change=0;
  220.  
  221.  
  222.   god=0;
  223.  
  224.   player_number=number;
  225.   cx1=0;
  226.   cy1=0;
  227.   cx2=100;
  228.   cy2=100;
  229.   focus=Focus;
  230.   next=Next;
  231.   shift_down=SHIFT_DOWN_DEFAULT;
  232.   shift_right=SHIFT_RIGHT_DEFAULT;
  233.   x_suggestion=0;
  234.   y_suggestion=0;
  235.   b1_suggestion=0;
  236.   b2_suggestion=0;
  237.   b3_suggestion=0;
  238.   b4_suggestion=0;
  239.   pointer_x=0;
  240.   pointer_y=0;
  241.  
  242.   pan_x=0;
  243.   pan_y=0;
  244.   last_type=0;
  245.   freeze_time=0;
  246.  
  247.   if (total_weapons)
  248.   {
  249.     weapons=(long *)jmalloc(total_weapons*sizeof(long),"weapon array");
  250.     last_weapons=(long *)jmalloc(total_weapons*sizeof(long),"last weapon array");
  251.     memset(weapons,0xff,total_weapons*sizeof(long));   // set all to -1
  252.     memset(last_weapons,0xff,total_weapons*sizeof(long));   // set all to -1  
  253.   }
  254.  
  255.   if (total_weapons)
  256.     weapons[0]=0;
  257.   if (local_player())
  258.     sbar.associate(this);
  259.   sbar.need_refresh();
  260. }
  261.  
  262. long view::x_center() 
  263. {
  264.   if (!focus)
  265.     return (cx1+cx2)/2;
  266.   else
  267.     return focus->x; 
  268. }   
  269.  
  270. long view::y_center() 
  271.   if (!focus)
  272.     return (cy1+cy2)/2;
  273.   else
  274.     return focus->y; 
  275. }
  276.  
  277. void view::draw_character_damage()
  278. {   
  279.   if (focus && drawable())
  280.   {
  281.     if (last_hp!=focus->hp()) draw_hp();
  282.     int i;
  283.     for (i=0;i<total_weapons;i++)
  284.       if (weapons[i]!=last_weapons[i])
  285.       {
  286.     last_weapons[i]=weapons[i];
  287.         sbar.draw_ammo(screen,i,weapons[i],current_weapon==i);
  288.       }
  289.   }
  290. }
  291.  
  292.  
  293.  
  294. ushort make_sync()
  295. {
  296.   ushort x=0;
  297.   if (!current_level) return 0;
  298.   if (current_level)
  299.   {
  300.     view *f=player_list;
  301.     for (;f;f=f->next)
  302.     {
  303.       if (f->focus)
  304.       {
  305.     x^=(f->focus->x&0xffff);
  306.     x^=(f->focus->y&0xffff);
  307.       }
  308.     }
  309.   }
  310.   x^=rand_on;
  311.  
  312.   return x;
  313. }
  314.  
  315.  
  316.  
  317. void view::get_input()
  318. {
  319.   int sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4;
  320.   long sug_px,sug_py;
  321.  
  322.   if (DEFINEDP(symbol_function(l_get_local_input)))
  323.   {
  324.     void *ret=eval_function((lisp_symbol *)l_get_local_input,NULL);
  325.     sug_x=lnumber_value(CAR(ret));  ret=CDR(ret);
  326.     sug_y=lnumber_value(CAR(ret));  ret=CDR(ret);
  327.     if (CAR(ret)) sug_b1=1; else sug_b1=0; ret=CDR(ret);
  328.     if (CAR(ret)) sug_b2=1; else sug_b2=0;  ret=CDR(ret);
  329.     int x=lnumber_value(CAR(ret)); ret=CDR(ret);
  330.     if (x<0) sug_b3=1; else sug_b3=0;
  331.     if (x>0) sug_b4=1; else sug_b4=0;    
  332.     
  333.     long bx=lnumber_value(CAR(ret));  ret=CDR(ret);
  334.     long by=lnumber_value(CAR(ret));  ret=CDR(ret);
  335.     the_game->mouse_to_game(bx,by,sug_px,sug_py,this);
  336.  
  337.   } else
  338.   {
  339.     get_movement(0,sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4);
  340.     if (focus)
  341.     {
  342.       the_game->mouse_to_game(last_demo_mx,last_demo_my,sug_px,sug_py,this);
  343.       if (last_demo_mbut&1) sug_b2=1;
  344.       if (last_demo_mbut&2) sug_b1=1;
  345.     } else sug_px=sug_py=0;
  346.   }
  347.  
  348.  
  349.   if (view_changed())
  350.   {
  351.     base->packet.write_byte(SCMD_VIEW_RESIZE);
  352.     base->packet.write_byte(player_number);
  353.     base->packet.write_long(suggest.cx1);
  354.     base->packet.write_long(suggest.cy1);
  355.     base->packet.write_long(suggest.cx2);
  356.     base->packet.write_long(suggest.cy2);
  357.  
  358.     base->packet.write_long(suggest.pan_x);
  359.     base->packet.write_long(suggest.pan_y);
  360.     base->packet.write_long(suggest.shift_down);
  361.     base->packet.write_long(suggest.shift_right);
  362.   }
  363.  
  364.   if (weapon_changed())
  365.   {
  366.     base->packet.write_byte(SCMD_WEAPON_CHANGE);
  367.     base->packet.write_byte(player_number);
  368.     base->packet.write_long(suggest.new_weapon);
  369.   }
  370.  
  371.   base->packet.write_byte(SCMD_SET_INPUT);
  372.   base->packet.write_byte(player_number);
  373.  
  374.  
  375.   uchar mflags=0;
  376.   if (sug_x>0)
  377.     mflags|=1;
  378.   else if (sug_x<0)
  379.     mflags|=2;
  380.  
  381.   if (sug_y>0)
  382.     mflags|=4;
  383.   else if (sug_y<0)
  384.     mflags|=8;
  385.  
  386.   if (sug_b1) mflags|=16;
  387.   if (sug_b2) mflags|=32;
  388.   if (sug_b3) mflags|=64;
  389.   if (sug_b4) mflags|=128;
  390.  
  391.   base->packet.write_byte(mflags);
  392.  
  393.   base->packet.write_short((ushort)((short)sug_px));
  394.   base->packet.write_short((ushort)((short)sug_py));
  395.  
  396. }
  397.  
  398.  
  399. void view::add_chat_key(int key)  // return string if buf is complete
  400. {
  401.   int len=strlen(chat_buf);
  402.   if (key==JK_BACKSPACE)
  403.   {
  404.     if (len)
  405.     {
  406.       chat_buf[len-1]=0;
  407.       if (local_player() && chat)
  408.         chat->draw_user(chat_buf);
  409.     }
  410.   } else if (key!=JK_ENTER)
  411.   {
  412.     chat_buf[len]=key;
  413.     chat_buf[len+1]=0;
  414.     if (local_player() && chat)
  415.       chat->draw_user(chat_buf);
  416.   }
  417.  
  418.   if (len>38 || key==JK_ENTER)
  419.   {
  420.     if (DEFINEDP(symbol_function(l_chat_input)))
  421.     {
  422.       game_object *o=current_object;
  423.       current_object=focus;
  424.  
  425.       void *m=mark_heap(TMP_SPACE);
  426.       void *list=NULL;
  427.       push_onto_list(new_lisp_string(chat_buf),list);       
  428.       eval_function((lisp_symbol *)l_chat_input,list);
  429.       restore_heap(m,TMP_SPACE);
  430.  
  431.       current_object=o;
  432.  
  433.     } else
  434.     {           
  435.       if (chat)
  436.         chat->put_all(chat_buf);
  437.     }
  438.     chat_buf[0]=0;
  439.     if (local_player() && chat)
  440.       chat->draw_user(chat_buf);
  441.   }
  442. }
  443.  
  444. int view::process_input(char cmd, uchar *&pk)   // return 0 if something went wrong
  445. {
  446.   switch (cmd)
  447.   {
  448.     case SCMD_CHAT_KEYPRESS :
  449.     {
  450.       add_chat_key(*(pk++));
  451.     } break;
  452.     case SCMD_VIEW_RESIZE :
  453.     { 
  454.       long x[8];
  455.       memcpy(x,pk,8*4);  pk+=8*4;
  456.       cx1=lltl(x[0]);
  457.       cy1=lltl(x[1]);
  458.       cx2=lltl(x[2]);
  459.       cy2=lltl(x[3]);
  460.     
  461.       pan_x=lltl(x[4]);
  462.       pan_y=lltl(x[5]);
  463.       shift_down=lltl(x[6]);
  464.       shift_right=lltl(x[7]);
  465.       if (small_render)
  466.       {
  467.     small_render->resize(cx2-cx1+1,cy2-cy1+1);
  468.       }
  469.  
  470.       suggest.send_view=0;
  471.       if (local_player())
  472.         the_game->draw();
  473.       return 1;
  474.     }
  475.     case SCMD_WEAPON_CHANGE :
  476.     {
  477.       long x;
  478.       memcpy(&x,pk,4);  pk+=4;
  479.       current_weapon=lltl(x);
  480.  
  481.       if (local_player())
  482.         sbar.need_refresh();
  483.       suggest.send_weapon_change=0;
  484.       return 1;
  485.     } break;
  486.  
  487.     case SCMD_SET_INPUT :
  488.     {
  489.       uchar x=*(pk++);
  490.  
  491.       if (x&1) x_suggestion=1;
  492.       else if (x&2) x_suggestion=-1;
  493.       else x_suggestion=0;
  494.  
  495.       if (x&4) y_suggestion=1;
  496.       else if (x&8) y_suggestion=-1;
  497.       else y_suggestion=0;
  498.  
  499.       if (x&16) b1_suggestion=1; else b1_suggestion=0;
  500.       if (x&32) b2_suggestion=1; else b2_suggestion=0;
  501.       if (x&64) b3_suggestion=1; else b3_suggestion=0;
  502.       if (x&128) b4_suggestion=1; else b4_suggestion=0;
  503.  
  504.       ushort p[2];
  505.       memcpy(p,pk,2*2);  pk+=2*2;
  506.       
  507.       pointer_x=(short)(lstl(p[0]));
  508.       pointer_y=(short)(lstl(p[1]));
  509.     
  510.       return 1;
  511.     } break;
  512.     case SCMD_KEYPRESS : set_key_down(*(pk++),1); break;
  513.     case SCMD_EXT_KEYPRESS : set_key_down(*(pk++)+256,1); break;
  514.     case SCMD_KEYRELEASE : set_key_down(*(pk++),0); break;
  515.     case SCMD_EXT_KEYRELEASE : set_key_down(*(pk++)+256,0); break;
  516.   }
  517.   return 1;
  518. }
  519.  
  520. int view::local_player()
  521. {
  522.   return player_number==client_number();
  523. }
  524.  
  525. void view::next_weapon()
  526. {
  527.   int c=current_weapon;
  528.  
  529.   while (c<total_weapons-1)
  530.   {
  531.     c++;
  532.     if (weapon_total(c)>0)
  533.     {
  534.       suggest.send_weapon_change=1;
  535.       suggest.new_weapon=c;
  536.       return ;
  537.     }
  538.   }
  539.  
  540.   c=0;
  541.   while (c!=current_weapon)
  542.   {
  543.     if (weapon_total(c)>0)
  544.     {
  545.       suggest.send_weapon_change=1;
  546.       suggest.new_weapon=c;
  547.       return ;
  548.     }
  549.     c++;
  550.   }
  551. }
  552.  
  553. void view::last_weapon()
  554. {
  555.  
  556.   int c=current_weapon;
  557.  
  558.   while (c>=1)
  559.   {
  560.     c--;
  561.     if (weapon_total(c)>0 || c==0)
  562.     {
  563.       suggest.send_weapon_change=1;
  564.       suggest.new_weapon=c;
  565.       return ;
  566.     }
  567.   }
  568.  
  569.   c=total_weapons-1;
  570.   while (c!=current_weapon)
  571.   {
  572.     if (weapon_total(c)>0 || c==0)
  573.     {
  574.       suggest.send_weapon_change=1;
  575.       suggest.new_weapon=c;
  576.       return ;
  577.     }
  578.     c--;
  579.   }
  580.  
  581. }
  582.  
  583. int view::handle_event(event &ev)
  584. {
  585.   if (ev.type==EV_KEY)
  586.   {
  587.    switch (ev.key)
  588.    {
  589.      case '1' : 
  590.      case '2' :
  591.      case '3' :
  592.      case '4' :
  593.      case '5' :
  594.      case '6' :
  595.      case '7' :
  596.      { if (((dev&EDIT_MODE)==0) && (weapon_total(ev.key-'1')>0))
  597.        {
  598.      suggest.send_weapon_change=1;
  599.      suggest.new_weapon=ev.key-'1';
  600.        }
  601.      } break;
  602.  
  603.      case JK_HOME :
  604.      case JK_CTRL_L :
  605.      case JK_CTRL_R :
  606.      { if (total_weapons) last_weapon(); return 1; } break;
  607.      case JK_PAGEUP :
  608.      case JK_INSERT :
  609.      { if (total_weapons) next_weapon(); return 1;} break;
  610.    }
  611.  }
  612.   return 0;
  613. }
  614.  
  615.  
  616. void view::draw_hp()
  617.   if (focus)
  618.   {
  619.     int h=focus->hp();    
  620.     last_hp=h;
  621.     sbar.draw_health(screen,focus->hp());
  622.   } else
  623.     sbar.draw_health(screen,0);
  624. }
  625.  
  626. int view::drawable()
  627. {  
  628.   return local_player();
  629. }
  630.  
  631.  
  632. void recalc_local_view_space()   // calculates view areas for local players, should be called 
  633.                                  // when adding or deleting local players
  634. {
  635.   if (screen)
  636.   {
  637.     int t=total_local_players();
  638.     if (!t) return ;
  639.  
  640.     int Xres=small_render ? xres/2 : xres;
  641.     int Yres=small_render ? yres/2 : yres;
  642.  
  643.     int h=Yres/t;
  644.     int w=h*320/200,y=5;
  645.     if (w<300) w=300;
  646.  
  647.     for (view *f=player_list;f;f=f->next)
  648.     {
  649.       if (f->local_player())
  650.       {
  651.     f->suggest.cx1=Xres/2-w/2;
  652.     f->suggest.cx2=Xres/2+w/2;
  653.     if (f->suggest.cx1<2) f->suggest.cx1=2;
  654.     if (f->suggest.cx2>Xres-2) f->suggest.cx2=Xres-2;    
  655.  
  656.     f->suggest.cy1=y;
  657.     f->suggest.cy2=h-(total_weapons ? 33 : 0);
  658.  
  659.     f->suggest.shift_down=f->shift_down;
  660.     f->suggest.shift_right=f->shift_right;
  661.     f->suggest.pan_x=f->pan_x;
  662.     f->suggest.pan_y=f->pan_y;
  663.     f->suggest.send_view=1;
  664.  
  665.     if (!player_list->next)
  666.     {
  667.       f->cx1=f->suggest.cx1;
  668.       f->cy1=f->suggest.cy1;
  669.       f->cx2=f->suggest.cx2;
  670.       f->cy2=f->suggest.cy2;
  671.       f->suggest.send_view=0;
  672.     }
  673.     y+=h;
  674.       }
  675.     }
  676.   }
  677.  
  678. }
  679.  
  680.  
  681. void set_local_players(int total)
  682. {
  683.   int rdw=0;
  684.   if (total<1) return ;
  685.  
  686.   view *last=NULL;
  687.   for (view *f=player_list;f;f=f->next)
  688.   {
  689.     if (total && f->local_player())
  690.       total--;
  691.     else if (!total && f->local_player())  // too many local players, delete this one
  692.     {
  693.       view *n=last->next;
  694.       while (n && !n->local_player()) n=n->next;  // find next local player
  695.  
  696.       if (last)
  697.         last->next=n;
  698.       else        
  699.       {
  700.     if (n)    // make sure we have at least one local player
  701.           player_list=n;
  702.       }            
  703.       last=f;
  704.       rdw=1;
  705.     }
  706.   }
  707.   
  708.   while (total)   // see if we need to add new players
  709.   {
  710.     game_object *o=create(current_start_type,50,50);    
  711.     view *v;
  712.     if (!player_list)
  713.     {
  714.       player_list=new view(o,NULL,0);
  715.       v=player_list;
  716.     }
  717.     else
  718.     {
  719.       view *f=player_list;
  720.       for (;f && f->next;f=f->next);        
  721.       f->next=new view(o,NULL,f->player_number+1);
  722.       v=f->next;
  723.     }
  724.     v->cx1=320/2-155; v->cy1=200/2-95; v->cx2=320/2+155; v->cy2=200/2+(total_weapons ? 60 : 95);
  725.     v->focus->set_controller(v);
  726.     total--;
  727.     rdw=1;
  728.   }  
  729.   if (rdw)
  730.     recalc_local_view_space();
  731. }
  732.  
  733.  
  734. int total_local_players()
  735. {
  736.   int t=0;
  737.   for (view *f=player_list;f;f=f->next) 
  738.     if (f->local_player()) t++;
  739.   return t;
  740. }
  741.  
  742.  
  743. void view::resize_view(long Cx1, long Cy1, long Cx2, long Cy2)
  744. {
  745.   if (cx1!=Cx1 || cx2!=Cx2 || cy1!=Cy1 || cy2!=Cy2)
  746.   {
  747.     cx1=Cx1; cy1=Cy1;
  748.     cx2=Cx2; cy2=Cy2;
  749.     if (playing_state(the_game->state) && local_player())
  750.       the_game->draw(0);
  751.   }
  752. }
  753.  
  754.  
  755. void view::set_input(int cx, int cy, int b1, int b2, int b3, int b4, int px, int py)
  756. {
  757.   x_suggestion=cx;
  758.   y_suggestion=cy;
  759.   b1_suggestion=b1;
  760.   b2_suggestion=b2;
  761.   b3_suggestion=b3;
  762.   b4_suggestion=b4;
  763.   pointer_x=px;
  764.   pointer_y=py;
  765. }
  766.  
  767.  
  768.  
  769. void view::reset_player()
  770. {
  771.   if (focus)
  772.   {
  773.    
  774.     game_object *start=current_level ? current_level->get_random_start(320,focus->controller()) : 0;
  775.     focus->defaults();
  776.     if (start)
  777.     {
  778.       focus->x=start->x;
  779.       focus->y=start->y;
  780.       dprintf("reset position to %d %d\n",start->x,start->y);
  781.     } 
  782.     focus->set_state(stopped);
  783.     memset(weapons,0xff,total_weapons*sizeof(long));   
  784.     memset(last_weapons,0xff,total_weapons*sizeof(long));   
  785.  
  786.     shift_down=SHIFT_DOWN_DEFAULT;
  787.     shift_right=SHIFT_RIGHT_DEFAULT;
  788.  
  789.     if (total_weapons)
  790.       weapons[0]=0;  // give him the first weapon
  791.     current_weapon=0;
  792.  
  793.     memset(focus->lvars,0,figures[focus->otype]->tv*4);
  794.     focus->set_aistate(0);
  795.     if (figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR))
  796.     {
  797.       game_object *o=current_object;
  798.       current_object=focus;
  799.       eval_user_fun((lisp_symbol *)figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR),NULL);
  800.       current_object=o;
  801.     }
  802.     sbar.redraw(screen);
  803.  
  804.     int i;
  805.     for (i=0;i<focus->total_objects();i++)   // reset the vars for the attached objects
  806.     {      
  807.       game_object *o=focus->get_object(i);
  808.       memset(o->lvars,0,figures[o->otype]->tv*4);
  809.     }
  810.  
  811.   }
  812. }
  813.  
  814.  
  815.  
  816.  
  817.  
  818. object_node *make_player_onodes(int player_num)
  819. {
  820.   object_node *first=NULL,*last;
  821.   for (view *o=player_list;o;o=o->next)
  822.   {
  823.     if (o->focus && (player_num==-1 || o->player_number==player_num))
  824.     {
  825.       if (!object_to_number_in_list(o->focus,first))
  826.       {
  827.     object_node *q=new object_node(o->focus,NULL);
  828.     if (first)
  829.       last->next=q;
  830.     else first=q;
  831.     last=q;
  832.       }
  833.       for (int i=0;i<o->focus->total_objects();i++)
  834.       {
  835.     game_object *p=o->focus->get_object(i);
  836.  
  837.     if (!object_to_number_in_list(p,first))
  838.     {
  839.       object_node *q=new object_node(p,NULL);
  840.       if (first)
  841.         last->next=q;
  842.       else first=q;
  843.       last=q;
  844.     }
  845.       }      
  846.     }
  847.   }
  848.   return first;
  849. }
  850.  
  851.  
  852.  
  853.  
  854. enum { V_CX1, V_CY1, V_CX2, V_CY2,
  855.        V_SHIFT_DOWN, V_SHIFT_RIGHT,
  856.        V_GOD,
  857.        V_PLAYER_NUMBER,
  858.        V_DRAW_SOLID,
  859.        V_LIVES,
  860.        V_CURRENT_WEAPON,
  861.        V_X_SUGGESTION, V_Y_SUGGESTION, V_B1_SUGGESTION, V_B2_SUGGESTION, V_B3_SUGGESTION, V_B4_SUGGESTION,
  862.        V_PAN_X, V_PAN_Y,
  863.        V_NO_XLEFT, V_NO_XRIGHT, V_NO_YTOP, V_NO_YBOTTOM,
  864.        V_LAST_X, V_LAST_Y, V_LAST_LEFT, V_LAST_RIGHT, V_LAST_UP, V_LAST_DOWN,
  865.        V_LAST_B1, V_LAST_B2, V_LAST_B3, V_LAST_B4,
  866.        V_LAST_HP,
  867.        V_SECRETS, V_KILLS, V_TSECRETS, V_TKILLS,
  868.        V_AMBIENT,
  869.        V_POINTER_X, V_POINTER_Y,
  870.        V_LAST_LAST_X, V_LAST_LAST_Y,
  871.        V_FREEZE_TIME };
  872.  
  873. #define TVV (V_FREEZE_TIME+1)
  874.  
  875. static char *vv_names[TVV]={
  876.   "view.cx1",  "view.cy1",  "view.cx2",  "view.cy2", 
  877.   "view.shift_down",  "view.shift_right",
  878.   "view.god",
  879.   "view.player_number",
  880.   "view.draw_solid",
  881.   "view.lives",
  882.   "view.current_weapon",
  883.   "view.x_suggestion",  "view.y_suggestion",  
  884.    "view.b1_suggestion",  "view.b2_suggestion",  "view.b3_suggestion",  "view.b4_suggestion",
  885.   "view.pan_x",  "view.pan_y",
  886.   "view.no_xleft",  "view.no_xright",  "view.no_ytop",  "view.no_ybottom",
  887.   "view.last_x",  "view.last_y",  "view.last_left",  "view.last_right",  "view.last_up",  "view.last_down", 
  888.   "view.last_b1",  "view.last_b2",  "view.last_b3",  "view.last_b4",
  889.   "view.last_hp",
  890.   "view.secrets",  "view.kills",  "view.tsecrets",  "view.tkills",
  891.   "view.ambient",
  892.   "view.pointer_x",  "view.pointer_y",
  893.   "view.last_last_x",  "view.last_last_y",
  894.   "view.freeze_time"
  895. };
  896.  
  897.  
  898. int total_view_vars() 
  899. { return TVV;
  900. }
  901.  
  902. char *get_view_var_name(int num)
  903. { return vv_names[num]; }
  904.  
  905. long view::get_view_var_value(int num)
  906. {
  907.   switch (num)
  908.   {
  909.     case V_CX1 : return cx1; break;
  910.     case V_CY1 : return cy1; break;
  911.     case V_CX2 : return cx2; break;
  912.     case V_CY2 : return cy2; break;
  913.     case V_SHIFT_DOWN : return shift_down; break;
  914.     case V_SHIFT_RIGHT : return shift_right; break;
  915.     case V_GOD : return god; break;
  916.     case V_PLAYER_NUMBER : return player_number; break;
  917.  
  918.     case V_DRAW_SOLID : return draw_solid; break;
  919.     case V_CURRENT_WEAPON : return current_weapon; break;
  920.     case V_X_SUGGESTION : return x_suggestion; break;
  921.     case V_Y_SUGGESTION : return y_suggestion; break;
  922.     case V_B1_SUGGESTION : return b1_suggestion; break;
  923.     case V_B2_SUGGESTION : return b2_suggestion; break;
  924.     case V_B3_SUGGESTION : return b3_suggestion; break;
  925.     case V_B4_SUGGESTION : return b4_suggestion; break;
  926.  
  927.     case V_PAN_X : return pan_x; break;
  928.     case V_PAN_Y : return pan_y; break;
  929.     case V_NO_XLEFT : return no_xleft; break;
  930.     case V_NO_XRIGHT : return no_xright; break;
  931.     case V_NO_YTOP : return no_ytop; break;
  932.     case V_NO_YBOTTOM : return no_ybottom; break;
  933.     case V_LAST_X : return last_x; break;
  934.     case V_LAST_Y : return last_y; break;
  935.     case V_LAST_LEFT : return last_left; break;
  936.     case V_LAST_RIGHT : return last_right; break;
  937.     case V_LAST_UP : return last_up; break;
  938.     case V_LAST_DOWN : return last_down; break;
  939.     case V_LAST_B1 : return last_b1; break;
  940.     case V_LAST_B2 : return last_b2; break;
  941.     case V_LAST_B3 : return last_b3; break;
  942.     case V_LAST_B4 : return last_b4; break;
  943.     case V_LAST_HP : return last_hp; break;
  944.     case V_SECRETS : return secrets; break;
  945.     case V_KILLS : return kills; break;
  946.     case V_TSECRETS : return tsecrets; break;
  947.     case V_TKILLS : return tkills; break;
  948.     case V_AMBIENT : return ambient; break;
  949.     case V_POINTER_X : return pointer_x; break;
  950.     case V_POINTER_Y : return pointer_y; break;
  951.     case V_LAST_LAST_X : return last_last_x; break;
  952.     case V_LAST_LAST_Y : return last_last_y; break;
  953.     case V_FREEZE_TIME : return freeze_time; break;
  954.   }
  955.   return 0;
  956. }
  957.  
  958.  
  959.  
  960. long view::set_view_var_value(int num, long x)
  961. {
  962.   switch (num)
  963.   {
  964.     case V_CX1 : cx1=x; break;
  965.     case V_CY1 : cy1=x; break;
  966.     case V_CX2 : cx2=x; break;
  967.     case V_CY2 : cy2=x; break;
  968.     case V_SHIFT_DOWN : shift_down=x; break;
  969.     case V_SHIFT_RIGHT : shift_right=x; break;
  970.     case V_GOD : god=x; break;
  971.     case V_PLAYER_NUMBER : { player_number=x; if (local_player()) sbar.associate(this); }  break;
  972.  
  973.     case V_DRAW_SOLID : draw_solid=x; break;
  974.     case V_CURRENT_WEAPON : { current_weapon=x; sbar.need_refresh(); } break;
  975.     case V_X_SUGGESTION : x_suggestion=x; break;
  976.     case V_Y_SUGGESTION : y_suggestion=x; break;
  977.     case V_B1_SUGGESTION : b1_suggestion=x; break;
  978.     case V_B2_SUGGESTION : b2_suggestion=x; break;
  979.     case V_B3_SUGGESTION : b3_suggestion=x; break;
  980.     case V_B4_SUGGESTION : b4_suggestion=x; break;
  981.  
  982.     case V_PAN_X : pan_x=x; break;
  983.     case V_PAN_Y : pan_y=x; break;
  984.     case V_NO_XLEFT : no_xleft=x; break;
  985.     case V_NO_XRIGHT : no_xright=x; break;
  986.     case V_NO_YTOP : no_ytop=x; break;
  987.     case V_NO_YBOTTOM : no_ybottom=x; break;
  988.     case V_LAST_X : last_x=x; break;
  989.     case V_LAST_Y : last_y=x; break;
  990.     case V_LAST_LEFT : last_left=x; break;
  991.     case V_LAST_RIGHT : last_right=x; break;
  992.     case V_LAST_UP : last_up=x; break;
  993.     case V_LAST_DOWN : last_down=x; break;
  994.     case V_LAST_B1 : last_b1=x; break;
  995.     case V_LAST_B2 : last_b2=x; break;
  996.     case V_LAST_B3 : last_b3=x; break;
  997.     case V_LAST_B4 : last_b4=x; break;
  998.  
  999.     case V_LAST_HP : last_hp=x; break;
  1000.     case V_SECRETS : secrets=x; break;
  1001.     case V_KILLS : kills=x; break;
  1002.     case V_TSECRETS : tsecrets=x; break;
  1003.     case V_TKILLS : tkills=x; break;
  1004.     case V_AMBIENT : ambient=x; break;
  1005.     case V_POINTER_X : pointer_x=x; break;
  1006.     case V_POINTER_Y : pointer_y=x; break;
  1007.     case V_LAST_LAST_X : last_last_x=x; break; 
  1008.     case V_LAST_LAST_Y : last_last_y=x; break;
  1009.     case V_FREEZE_TIME : freeze_time=x; break;
  1010.   }
  1011.   return 1;
  1012. }
  1013.  
  1014.  
  1015. void view::configure_for_area(area_controller *a)
  1016. {
  1017.   if (a->ambient>=0 && a->ambient!=ambient)
  1018.   {
  1019.     if (ambient>a->ambient)
  1020.     {
  1021.       ambient-=a->ambient_speed;
  1022.       if (ambient<a->ambient) 
  1023.         ambient=a->ambient;
  1024.     }
  1025.     else 
  1026.     {
  1027.       ambient+=a->ambient_speed;
  1028.       if (ambient>a->ambient) 
  1029.         ambient=a->ambient;
  1030.     }    
  1031.   }
  1032.  
  1033.   if (!view_shift_disabled)
  1034.   {
  1035.     if (a->view_xoff!=pan_x)
  1036.     {
  1037.       if (pan_x>a->view_xoff)
  1038.       {
  1039.     pan_x-=a->view_xoff_speed;
  1040.     if (pan_x<a->view_xoff) 
  1041.         pan_x=a->view_xoff;
  1042.       }
  1043.       else
  1044.       {
  1045.     pan_x+=a->view_xoff_speed;
  1046.     if (pan_x>a->view_xoff) 
  1047.         pan_x=a->view_xoff;
  1048.       }
  1049.     }
  1050.  
  1051.     if (a->view_yoff!=pan_y)
  1052.     {
  1053.       if (pan_y>a->view_yoff)
  1054.       {
  1055.     pan_y-=a->view_yoff_speed;
  1056.     if (pan_y<a->view_yoff) 
  1057.         pan_y=a->view_yoff;
  1058.       }
  1059.       else
  1060.       {
  1061.     pan_y+=a->view_yoff_speed;
  1062.     if (pan_y>a->view_yoff) 
  1063.         pan_y=a->view_yoff;
  1064.       }
  1065.     }  
  1066.   }
  1067. }
  1068.  
  1069.  
  1070. void process_packet_commands(uchar *pk, int size)
  1071. {
  1072.   long sync_short=-1;
  1073.  
  1074.   if (!size) return ;
  1075.   pk[size]=SCMD_END_OF_PACKET;
  1076.  
  1077.   uchar cmd;
  1078.   int already_reloaded=0;
  1079.  
  1080.  
  1081.   do
  1082.   {
  1083.     cmd=*(pk++);
  1084.     switch (cmd)
  1085.     {
  1086.       case SCMD_WEAPON_CHANGE :
  1087.       case SCMD_SET_INPUT :
  1088.       case SCMD_VIEW_RESIZE :
  1089.       case SCMD_KEYPRESS :
  1090.       case SCMD_KEYRELEASE :
  1091.       case SCMD_EXT_KEYPRESS :
  1092.       case SCMD_EXT_KEYRELEASE :
  1093.       case SCMD_CHAT_KEYPRESS :
  1094.       {
  1095.     uchar player_num=*(pk++);
  1096.  
  1097.     view *v=player_list;
  1098.     for (;v && v->player_number!=player_num;v=v->next);
  1099.     if (v)
  1100.     {
  1101.       if (v->player_number==player_num)
  1102.       v->process_input(cmd,pk);
  1103.     }      
  1104.     else
  1105.     {
  1106.       dprintf("Evil error : bad player number in packet\n");
  1107.       return ;
  1108.     }
  1109.       } break;
  1110.       case SCMD_RELOAD :
  1111.       {
  1112.     if (!already_reloaded)
  1113.     {
  1114.       net_reload();
  1115.       already_reloaded=1;
  1116.     }
  1117.       } break;
  1118.  
  1119.       case SCMD_SYNC :
  1120.       {
  1121.     ushort x;
  1122.     memcpy(&x,pk,2);  pk+=2;
  1123.     x=lstl(x);
  1124.     if (demo_man.current_state()==demo_manager::PLAYING)
  1125.     sync_short=make_sync();
  1126.  
  1127.     if (sync_short==-1)
  1128.     sync_short=x;
  1129.     else if (x!=sync_short && !already_reloaded)
  1130.     {
  1131.       dprintf("out of sync %d (packet=%d, calced=%d)\n",current_level->tick_counter(),x,sync_short);
  1132.       if (demo_man.current_state()==demo_manager::NORMAL)
  1133.         net_reload();
  1134.       already_reloaded=1;
  1135.     }
  1136.       } break;
  1137.       case SCMD_DELETE_CLIENT :
  1138.       {
  1139.     uchar player_num=*(pk++);
  1140.     view *v=player_list,*last=NULL;
  1141.     for (;v && v->player_number!=player_num;v=v->next)
  1142.     last=v;
  1143.     if (!v)
  1144.     dprintf("evil : delete client %d, but no such client\n");
  1145.     else
  1146.     {
  1147.  
  1148.       // make a list of all objects associated with this player
  1149.       object_node *on=make_player_onodes(player_num);   
  1150.       while (on)
  1151.       {
  1152.         current_level->delete_object(on->me);
  1153.         object_node *last=on;
  1154.         on=on->next;
  1155.         delete last;
  1156.       }
  1157.  
  1158.       v->focus=NULL;
  1159.       if (last)
  1160.       last->next=v->next;
  1161.       else player_list=player_list->next;
  1162.  
  1163.       delete v;
  1164.     }
  1165.       } break;
  1166.       defualt :
  1167.       dprintf("Unknown net command %d\n",cmd);
  1168.  
  1169.     }
  1170.   } while (cmd!=SCMD_END_OF_PACKET);
  1171. }
  1172.